// 染色法判断二分图的原理是: 一个图是二分图当且仅当其中不存在奇数环
// 时间复杂度：O(n+m)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100010, M = 200010;
int n, m;
int h[N], e[M], ne[M], idx;
// color数组存储的是每个节点被染的颜色
int color[N];

int add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

bool bfs(int u, int c)
{
    // 进入这个循环的肯定是没有染色的点
    color[u] = c;
    for (int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        // 3-c的意思是如果当前染的是1号颜色则返回二号颜色，反之
        if (color[j] == 0)
        {
            if (!bfs(j, 3 - c))
                return false;
        }
        else if (color[j] == c)
            return false;
    }
    return true;
}

// 上下两个代码的区别是上面的代码在递归回退的时候不会直接return，如果成功会进入循环的下一阶段
// 而下面的代码不会等到循环结束
// 也就是说没有将所有边都成功连接
/*bool bfs(int u, int c)
{
    //进入这个循环的肯定是没有染色的点
    color[u] = c;
    for(int i = h[u]; ~i; i = ne[i])
    {
        int j = e[i];
        //3-c的意思是如果当前染的是1号颜色则返回二号颜色，反之
        if(color[j] == 0) return bfs(j, 3-c);
        else
        {
            if(color[j] == c) return false;
        }
    }
    return true;
}*/

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    memset(h, -1, sizeof h);
    cin >> n >> m;
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        add(a, b), add(b, a);
    }
    int i = 1;
    for (; i <= n; ++i)
    {
        // 如果发现该节点还没有染色，就继续染色
        if (!color[i])
            if (!bfs(i, 1))
                break;
    }
    if (i == n + 1)
        cout << "Yes\n";
    else
        cout << "No";
    return 0;
}

// 细节
// 注意染色不能在一半中断
